namespace SenenFernandez.SmartExtensionMethods
{
    using System;
    using System.Runtime.InteropServices;
    using System.Runtime.Versioning;
    using System.Windows;

    public class Display
    {
        private const int DisplayinfofPrimary = 0x00000001;

        /// <summary>
        /// Screen Area.
        /// </summary>
        public Rect Bounds { get; private set; }

        /// <summary>
        /// Working Area.
        /// </summary>
        public Rect WorkingArea { get; private set; }

        /// <summary>
        /// Display Name.
        /// </summary>
        public string Name { get; private set; }

        /// <summary>
        /// IsPrimary Display.
        /// </summary>
        public bool IsPrimary { get; private set; }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        [ResourceExposure(ResourceScope.None)]
        private static extern bool GetMonitorInfo(HandleRef handle, [In, Out] DisplayInfoEx info);

        public Display(IntPtr display, IntPtr handle)
        {
            var info = new DisplayInfoEx();
            GetMonitorInfo(new HandleRef(null, display), info);
            Bounds = new Rect(
                info.display.Left, info.display.Top,
                info.display.Width - info.display.Left,
                info.display.Height - info.display.Top);
            WorkingArea = new Rect(
                info.work.Left, info.work.Top,
                info.work.Width - info.work.Left,
                info.work.Height - info.work.Top);
            IsPrimary = ((info.flags & DisplayinfofPrimary) != 0);
            Name = new string(info.szDevice).TrimEnd((char)0);
        }

        public override string ToString()
        {
            return string.Format("{0}: Left=\"{1}\" Top=\"{2}\" Width=\"{3}\" Height=\"{4}\"", 
                Name, WorkingArea.Left, WorkingArea.Top, WorkingArea.Width, WorkingArea.Height);
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
        private class DisplayInfoEx
        {
            internal int size = Marshal.SizeOf(typeof(DisplayInfoEx));
            internal Rectangle display;
            internal Rectangle work;
            internal int flags;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            internal readonly char[] szDevice = new char[32];
        }
    }
}